<?php
/**
 * ============================================================================
 * 版权所有 2017-2077 tpframe工作室，并保留所有权利。
 * @link http://www.tpframe.com/
 * @copyright Copyright (c) 2017 TPFrame Software LLC
 * ----------------------------------------------------------------------------
 * 这不是一个自由软件！未经本公司授权您只能在不用于商业目的的前提下对程序代码进行修改和使用；
 * 不允许对程序代码以任何形式任何目的的再发布。
 * ============================================================================
 */
namespace app\frontend\logic;
use \tpfcore\util\Tree;
use \tpfcore\util\Data;
use \tpfcore\Core;
use tpfcore\util\DocParser;
use tpfcore\helpers\StringHelper;
/**
 *  导出tcms逻辑
 */
class ExportTcms extends FrontendBase
{
	protected  $config = [
        'title'=>'tcms 线上自动生成',
        'version'=>'1.0',
        'copyright'=>'Powered By TPFrame',
        'base_app' => ['config','lang'],
        'base_controller' => ["Auth","FrontendBase","ErrorController","Upload"],   // 必须控制器列表
        'base_logic'=>["FrontendBase"],
        'base_service'=>["FrontendBase"],
        'base_model'=>['FrontendBase'],
        'base_validate'=>['FrontendBase'],

        'base_html'=>['base','footer','header','top','assets'],

        'filter_method'=>['_empty']
    ];
    public $position;
    protected $templates=[];
	/**
     * 获取关系列表
     * @return array
     */
    public function getFileList($templates=[])
    {
    	$controller =$this->getTcmsClass($templates);

    	$result = $this->getTcmsRelation($controller);
    	$arr=[
    		"controller"=>$this->config['base_controller'],
    		"logic"=>$this->config['base_logic'],
    		"service"=>$this->config['base_service'],
    		"model"=>$this->config['base_model'],
    		"validate"=>$this->config['base_validate'],
    	];

    	foreach ($result as $key => $value) {
    		$arr['controller'][]=$value['class'];
    		foreach ($value['relation'] as $k2 => $v2) {
                !empty($v2['service']) && $arr['service']=array_unique(array_merge($arr['service'],explode(",",$v2['service'])));
    			!empty($v2['logic']) && $arr['logic']=array_unique(array_merge($arr['logic'],explode(",",$v2['logic'])));
    			!empty($v2['model']) && $arr['model']=array_unique(array_merge($arr['model'],explode(",",$v2['model'])));
    			!empty($v2['validate']) && $arr['validate']=array_unique(array_merge($arr['validate'],explode(",",$v2['validate'])));
    		}
    	}
        $arr['base']=$this->config['base_app'];
    	$arr['template']=array_merge($this->config['base_html'],$this->templates);

    	return $arr;
    }

    private function getTcmsClass($templates=[]){
    	$class =[];
    	foreach ($templates as $key => $value) {
    		$class_name = explode("_", $value);
    		$class[]="app\\tcms\\controller\\".$class_name[0];

            $this->templates[]=StringHelper::s_format_underline($class_name[0]).'\\'.$value;

    	}
    	return $class;
    }

    private function getTcmsRelation($controller=[]){
    	$i=0;
        foreach ($controller as $class)
        {
            if(class_exists($class))
            {
                $reflection = new \ReflectionClass($class);
                $module[$i]['class'] = $reflection->getShortName();
                $method = $reflection->getMethods(\ReflectionMethod::IS_PUBLIC);
                $filter_method = array_merge(['__construct'], $this->config['filter_method']);
                $module[$i]['relation'] = [];
                foreach ($method as $action){
                    if(!in_array($action->name, $filter_method) && $action->class == $class)
                    {   
                        $doc = new DocParser();
                        $doc_str = $action->getDocComment();
                        if($doc_str)
                        {
                            $module[$i]['relation'][$action->name] = $doc->parse($doc_str);
                        }
                    }
                }
            }
            $i++;
        }
        return $module;
    }

    public function package($files){
        try {
            foreach ($files as $key => $value) {
                switch ($key) {
                    case 'template':
                        foreach ($value as $k2 => $v2) {
                            $source_file =ROOT_PATH."theme\\app\\tcms";

                            $dirto=ROOT_PATH."tcms_package\\theme\\app\\tcms";

                            $this->copyFile($source_file,$dirto,$v2);

                        }
                        break;
                    case 'base':
                        foreach ($value as $k2 => $v2) {
                            $source_file = ROOT_PATH."application\\tcms";

                            $dirto = ROOT_PATH."tcms_package\\application\\tcms";

                            $this->copyFile($source_file,$dirto,$v2,"php");
                        }
                        break;
                    default:
                        $this->position=$key;
                        foreach ($value as $k2 => $v2) {

                            $source_file = ROOT_PATH."application\\tcms\\$key";

                            $dirto = ROOT_PATH."tcms_package\\application\\tcms\\$key";

                            $this->copyFile($source_file,$dirto,$v2,"php");

                        }
                        break;
                }
            }
            return [0,"生成完成"];
        } catch (Exception $e) {
            echo $e->getMessage();
        }
    }

    private function copyFile($dirfrom, $dirto , $file_name="",$ext ="html") {
        //如果目录不存在，则建立之
        if(!file_exists($dirto)){
            mkdir($dirto,0777, true);
        }
        
        if(is_dir($dirfrom."\\$file_name")){
            @mkdir($dirto."\\$file_name",0777,true);
            $handle = opendir($dirfrom."\\$file_name"); //打开当前目录
            //循环读取文件
            while(false !== ($file = readdir($handle))) {
                if($file != '.' && $file != '..'){
                    //生成源文件名
                    $filefrom = $dirfrom."\\$file_name".DIRECTORY_SEPARATOR.$file;
                    //生成目标文件名
                    $fileto = $dirto."\\$file_name".DIRECTORY_SEPARATOR.$file;

                    if(is_dir($filefrom)){

                        $this->copyDir($filefrom, $fileto, $file);

                    } else {
                        copy($filefrom, $fileto);

                    }
                }
            }
        }
        elseif(is_file($dirfrom."\\$file_name")){
            //生成源文件名
            $filefrom = $dirfrom.DIRECTORY_SEPARATOR."$file_name";
            //生成目标文件名
            $fileto = $dirto.DIRECTORY_SEPARATOR."$file_name";
            copy($filefrom,$fileto);
        }else{
            if(is_file($dirfrom."\\$file_name.$ext")){
                //生成源文件名
                $filefrom = $dirfrom.DIRECTORY_SEPARATOR."$file_name.$ext";
                //专门针对模板文件进行处理的
                $file_name_base=strstr($file_name,"__",true);   // 有__肯定是模板文件
                if($file_name_base){
                    $file_name_dir ="";
                    if(strstr($file_name_base,"\\",true)){
                        $file_name_dir = strstr($file_name_base,"\\",true);
                        $file_name_base = substr($file_name_base,stripos($file_name_base,"\\")+1);
                    }

                    $new_name = substr($file_name_base,stripos($file_name_base,"_")+1);

                    $new_name = $file_name_dir?$file_name_dir."\\".$new_name:$new_name;

                }else{
                    $new_name=$file_name;
                }
                //生成目标文件名
                $fileto = $dirto.DIRECTORY_SEPARATOR."$new_name.$ext";
                
                $has_dir=strstr($file_name,"\\",true);

                if($has_dir && !file_exists($dirto.DIRECTORY_SEPARATOR."$has_dir")){
                    mkdir($dirto.DIRECTORY_SEPARATOR."$has_dir",0777, true);
                }

                copy($filefrom,$fileto);

                /** 删除对应的注解 **/
                if($this->position==="controller"){
                    
                    $content = file_get_contents($fileto);

                    $content= preg_replace("/\/\*\*([\s\S]*)\*\//", "", $content);

                    file_put_contents($fileto, $content);
                }
            }
        }
    }

    private function copyDir($dirfrom,$dirto){
        //如果目录不存在，则建立之
        if(!file_exists($dirto)){
            mkdir($dirto,0777, true);
        }
        if(is_dir($dirfrom)){
            $handle = opendir($dirfrom);
            //循环读取文件
            while(false !== ($file = readdir($handle))) {
                if($file != '.' && $file != '..'){
                    //生成源文件名
                    $filefrom = $dirfrom.DIRECTORY_SEPARATOR.$file;
                    //生成目标文件名
                    $fileto = $dirto.DIRECTORY_SEPARATOR.$file;

                    if(is_dir($filefrom)){ //如果是子目录，则进行递归操作

                        $this->copyDir($filefrom, $fileto, $file);

                    } else {

                        copy($filefrom, $fileto);

                    }
                }
            }
        }
    }
}